﻿using System;
using System.IO;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
//using System.Xml.Linq;
using System.Text;
using System.Windows.Forms;
using System.Drawing.Drawing2D;
using System.Text.RegularExpressions;
using System.Runtime.InteropServices;


namespace RainmeterCustomized
{
    public partial class MainForm : Form
    {
        /// <summary>
        /// 皮肤目录的相对路径
        /// </summary>
        private String folderPath = "mySkin";

        /// <summary>
        /// 配置文件名
        /// </summary>
        private String configName = "Launcher.ini";

        /// <summary>
        /// 皮肤工作目录的根路径
        /// </summary>
        private String absPath = "";

        /// <summary>
        /// 当前路径
        /// </summary>
        private String currentPath = "";

        /// <summary>
        /// 保存当前控件列表， 用于后续操作
        /// </summary>
        private List<Control> controlList = new List<Control>();

        /// <summary>
        /// 计数器， 用于临时命名
        /// </summary>
        private Int32 tmpNameCount = 0;

        /// <summary>
        /// 用于保存当picBoxCMS弹出二级菜单时的sourceControl， 解决弹出菜单时该属性丢失问题
        /// </summary>
        private Control srcCtrlOfPicBoxCMS;

        /// <summary>
        /// 当前选中操作的控件
        /// </summary>
        private PanelExtend currentControl;

        /// <summary>
        /// 上一个meter的坐标， 用于计算相对坐标
        /// </summary>
        private Point lastMeterPosition = new Point(0, 0);

        private Size lastMeterSize = new Size(0, 0);

        private Size oldPanelSize;
        public MainForm()
        {
            InitializeComponent();
        }

        #region 主窗体加载和缩放
        private void MainForm_Load(object sender, EventArgs e)
        {
            this.sysBgCMSI.PerformClick();

            this.mainPicBox.Location = new Point(0, 0);

            this.mainPicBox.AllowDrop = true;
            this.mainPicBox.DragDrop += new DragEventHandler(PicBox_DragDrop);
            this.mainPicBox.DragEnter += new DragEventHandler(PicBox_DragEnter);

            this.DoubleBuffered = true;
            oldPanelSize = panel1.Size;
           
        }
        #endregion

        #region 初始化ini文件内容
        /// <summary>
        /// 初始化的ini文件内容
        /// </summary>
        /// <returns>ini内容</returns>
        private String getInitIniFileContent()
        {
            StringBuilder str = new StringBuilder();
            str.AppendLine(";*******This is Rainmeter config file produced by RainmeterCustomized");
            str.AppendLine(";*******You can modify this file yourself, but make sure that your modification is right");
            str.AppendLine(";*******Thank you for using RainmeterCustomized, if you have any questions, contact me by e-mail xiazhan2016@126.com .");
            str.AppendLine("[Rainmeter]");
            str.AppendLine("Author=RainmeterCustomized");
            str.AppendLine("\r\n");

            str.AppendLine(";Metadata region start ...");
            str.AppendLine("[Metadata]");
            str.AppendLine("Name=");
            str.AppendLine(";Metadata region end ...");
            str.AppendLine("Update=1000");

            str.AppendLine("\r\n");
            str.AppendLine(";Variables region start ...");
            str.AppendLine("[Variables]");
            str.AppendLine("RCText=RainmeterCustomized");
            str.AppendLine(";Variables region end ...");
            str.AppendLine("\r\n");

            str.AppendLine(";Labels region start ...");
            str.AppendLine("[RCTool]");
            str.AppendLine("Meter=Image");
            str.AppendLine(@"ImageName=#@#images\RCTool.png");
            str.AppendLine("X=100");
            str.AppendLine("Y=100");
            str.AppendLine("Hidden=1");

            return str.ToString();
        }
        #endregion


        #region 分析ini内容并显示
        private void AnalyseIniAndShow()
        {
            try
            {
                INIOperationClass iniRWTool = new INIOperationClass(Path.Combine(absPath, configName));

                String[] sections = iniRWTool.INIGetAllSectionNames();

                foreach (String section in sections)
                {
                    if (section.ToLower().Equals("variables"))
                    {
                        String[] keyValues = iniRWTool.INIGetAllItems(section);
                        foreach (String keyValue in keyValues)
                        {
                            try
                            {
                                String[] tokens = keyValue.Split('=');
                                String name = tokens[0];
                                String path = tokens[1];
                                Program.progList.Add(name, new VariablesClass.ProgramObject(name, path, ""));
                            }
                            catch
                            {
                            }
                        }
                    }
                    else if (section.ToLower().Equals("metadata"))
                    {
                    }
                    else if (section.ToLower().Equals("rainmeter"))
                    {
                    }
                    else
                    {
                        String meterType = iniRWTool.INIGetStringValue(section, "Meter", "");
                        String X_Str = iniRWTool.INIGetStringValue(section, "X", "0");
                        String Y_Str = iniRWTool.INIGetStringValue(section, "Y", "0");
                        X_Str = StaticMethod.GetRealValue(X_Str);
                        Y_Str = StaticMethod.GetRealValue(Y_Str);
                        //     Int32 W = Convert.ToInt32(iniRWTool.INIGetStringValue(section, "W", "0"));
                        //      Int32 H = Convert.ToInt32(iniRWTool.INIGetStringValue(section, "H", "0"));
                        Point relLocation = StaticMethod.XYGetAbsoluteValue(X_Str, Y_Str, lastMeterPosition, lastMeterSize);

                        if (meterType.ToLower().Equals("string"))
                        {
                            String text = iniRWTool.INIGetStringValue(section, "Text", "");
                            text = StaticMethod.GetRealValue(text);
                            MyLabel label = new MyLabel(text, relLocation);
                            label.MouseDown += new MouseEventHandler(Label_MouseDown);
                            label.MouseUp += new MouseEventHandler(Label_MouseUp);
                            this.toolTip1.SetToolTip(label, label.Location.ToString());
                            this.mainPicBox.Controls.Add(label);
                        }
                        else if (meterType.ToLower().Equals("button"))
                        {
                        }
                        else if (meterType.ToLower().Equals("image"))
                        {
                            String imagePath = iniRWTool.INIGetStringValue(section, "ImageName", "");

                            imagePath = imagePath.ToLower();
                            imagePath = imagePath.Replace(@"#currentpath#", absPath + "\\");
                            imagePath = imagePath.Replace(@"#@#", Path.Combine(absPath, "@Resources\\"));

                            if (!Path.IsPathRooted(imagePath))
                            {
                                imagePath = Path.Combine(absPath, imagePath);
                            }

                            if (String.IsNullOrEmpty(imagePath.Trim())) continue;
                            if (!File.Exists(imagePath))
                            {
                                MessageBox.Show("亲，" + imagePath + " 找不到呐，你再去瞅瞅？");
                                continue;
                            }

                            MyPictureBox pb = this.AddPicBox(section, imagePath, relLocation);
                            if (pb == null) continue;
                            lastMeterPosition = pb.Location;
                            lastMeterSize = pb.Size;

                            foreach (String actionName in VariablesClass.ConstData.SupportActionList)
                            {
                                String actionPath = iniRWTool.INIGetStringValue(section, actionName, "");
                                if (actionPath != null && !actionPath.Trim().Equals(""))
                                {
                                    pb.AddAction(actionName, actionPath);
                                }
                            }
                            ///更新提示
                            StringBuilder tips = new StringBuilder();
                            tips.AppendLine(pb.Name.ToString());
                            tips.AppendLine(pb.RelLocation.ToString());
                            foreach (KeyValuePair<String, String> kvPair in pb.GetActionList())
                            {
                                String action = kvPair.Value;
                                tips.AppendLine(kvPair.Key + ":" + action);
                            }
                            toolTip1.SetToolTip(pb, tips.ToString());
                            //*/
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show("很抱歉， 解析ini文件出错了， 错误原因:" + ex.Message);
            }
        }
        #endregion

        /// <summary>
        ///   The ColHeader class is a ColumnHeader object with an 
        ///   added property for determining an ascending or descending sort.
        ///   True specifies an ascending order, false specifies a descending order.
        /// </summary>
        public class ColHeader : ColumnHeader
        {
            public bool ascending;
            public ColHeader(string text, int width, HorizontalAlignment align, bool asc)
            {
                this.Text = text;
                this.Width = width;
                this.TextAlign = align;
                this.ascending = asc;
            }
        }

        #region 更新目录列表
        /// <summary>
        /// 更新皮肤工作目录列表
        /// </summary>
        /// <param name="currentPath">当前所在路径</param>
        private void updateWorkspaceLV(String currentPath)
        {
            workspaceLV.BeginUpdate();
            workspaceLV.Clear();
            smallImageList.Images.Clear();
            largeImageList.Images.Clear();
            try
            {
                DirectoryInfo Dir = new DirectoryInfo(currentPath);//创建目录对象。

                smallImageList.Images.Add(Properties.Resources.upper_small);
                largeImageList.Images.Add(Properties.Resources.upper_large);


                int iItem = 0;
                ListViewItem LiItem = new ListViewItem("返回上层", 0);
                workspaceLV.Items.Insert(iItem, LiItem);
                iItem++;
                foreach (DirectoryInfo di in Dir.GetDirectories())
                {
                    smallImageList.Images.Add(IconTool.GetIconForFolder(IconTool.Small, false));
                    largeImageList.Images.Add(IconTool.GetIconForFolder(IconTool.Large, false));
                    LiItem = new ListViewItem(di.Name, iItem);
                    LiItem.Tag = di.FullName;
                    LiItem.Text = di.Name;
                    workspaceLV.Items.Insert(iItem, LiItem);
                    iItem++;
                }

                FileInfo[] dirFiles = Dir.GetFiles();
                foreach (FileInfo fi in dirFiles)
                {
                    try
                    {
                        Stream s = File.OpenRead(fi.FullName);
                        Image originImage = Image.FromStream(s);
                        s.Close();
                        Image smallImage = originImage.GetThumbnailImage(16, 16, null, IntPtr.Zero);
                        Image largeImage = originImage.GetThumbnailImage(32, 32, null, IntPtr.Zero);
                        smallImageList.Images.Add(smallImage);
                        largeImageList.Images.Add(largeImage);
                    }
                    catch
                    {
                        Icon smallIcon = IconTool.GetIconForFileExtension(fi.Extension, IconTool.Small, false);
                        Icon largeIcon = IconTool.GetIconForFileExtension(fi.Extension, true, false);
                        smallImageList.Images.Add(smallIcon);
                        largeImageList.Images.Add(largeIcon);
                    }
                    
                    LiItem = new ListViewItem(fi.Name, iItem);
                    LiItem.Tag = fi.Name;
                    LiItem.Text = fi.Name;
                    workspaceLV.Items.Insert(iItem, LiItem);
                    iItem++;
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "错误", 0, MessageBoxIcon.Error);
            }
            this.Cursor = Cursors.Arrow;
            workspaceLV.EndUpdate();
        }
        #endregion

        #region 添加控件到工作区域
        /// <summary>
        /// 添加控件到工作区域
        /// </summary>
        /// <param name="name"></param>
        /// <param name="imagePath"></param>
        /// <param name="relLocation"></param>
        /// <returns></returns>
        private MyPictureBox AddPicBox(String name, String imagePath, Point relLocation)
        {
            Stream s = File.Open(imagePath, FileMode.Open, FileAccess.Read);
            Image img = Image.FromStream(s);
            MyPictureBox pb = new MyPictureBox(img);
            pb.Name = name;
            pb.Name = name;
            pb.BackColor = Color.Transparent;
            pb.Image = img;
            pb.Size = img.Size;
            pb.ImagePath = imagePath;

            Int32 _X = relLocation.X - panel1.HorizontalScroll.Value;
            Int32 _Y = relLocation.Y - panel1.VerticalScroll.Value;
            if (_X < 0) _X = 0;
            if (_Y < 0) _Y = 0;
            pb.Location = new Point(_X, _Y);
            //   pb.Location = relLocation;
            pb.RelLocation = relLocation;

            pb.Cursor = Cursors.Hand;
            pb.ContextMenuStrip = this.picBoxCMS;
            pb.AllowDrop = true;
            pb.DragDrop += new DragEventHandler(PicBox_DragDrop);
            pb.DragEnter += new DragEventHandler(PicBox_DragEnter);
            pb.MouseDown += new MouseEventHandler(PicBox_MouseDown);
            pb.MouseUp += new MouseEventHandler(PicBox_MouseUp);
            //  this.panel1.Controls.Add(pb);
            mainPicBox.Controls.Add(pb);
            this.controlList.Add(pb);
            pb.BringToFront();
            s.Close();
            return pb;

        }
        #endregion

        #region 清空工作区域
        /// <summary>
        /// 清空当前工作区域列表
        /// </summary>
        private void ClearWorkSpace()
        {
            lock (Program.progList)
                Program.progList.Clear();
            lock (mainPicBox.Controls)
            {
                /*
                foreach (MyPictureBox pb in mainPicBox.Controls)
                {
                    if (pb != null)
                    {
                        mainPicBox.Controls.Remove(pb);
                        pb.Dispose();
                    }
                }
                */
                mainPicBox.Controls.Clear();
                this.controlList.Clear();
            }

        }
        #endregion
        
        #region 新建皮肤
        private void createTSMI_Click(object sender, EventArgs e)
        {
            this.ClearWorkSpace();
            try
            {
                FolderBrowserDialog fbd = new FolderBrowserDialog();
                fbd.Description = "选择皮肤的工作目录, 用于保存皮肤相关的资源和配置文件";
                if (fbd.ShowDialog() == DialogResult.OK)
                {
                    absPath = Path.Combine(fbd.SelectedPath, folderPath);
                    if (!Directory.Exists(absPath))
                    {
                        Directory.CreateDirectory(absPath);
                        Directory.CreateDirectory(Path.Combine(absPath, "@Resources"));
                        Directory.CreateDirectory(Path.Combine(absPath, @"@Resources\images"));
                        Directory.CreateDirectory(Path.Combine(absPath, @"@Resources\font"));
                        Directory.CreateDirectory(Path.Combine(absPath, @"@Resources\other"));
                        FileStream iniFile = new FileStream(Path.Combine(absPath, configName), FileMode.Create);
                        byte[] data = new UTF8Encoding().GetBytes(this.getInitIniFileContent());
                        iniFile.Write(data, 0, data.Length);
                        iniFile.Close();
                        Image img = Properties.Resources.RCTool;
                        img.Save(Path.Combine(absPath, @"@Resources\images\RCTool.png"));
                        currentPath = "";
                        this.updateWorkspaceLV(Path.Combine(absPath, currentPath));
                        this.workspaceLV.AllowDrop = true;
                    }
                    else
                    {
                        MessageBox.Show("mySkin目录存在，请选择新目录！");
                    }
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show("~`·_·`~好像发生了点什么问题， 联系作者吧^_^ :" + ex.Message, "错误", 0, MessageBoxIcon.Error);
            }
        }
        #endregion

        #region 加载皮肤
        private void loadTSMI_Click(object sender, EventArgs e)
        {
            this.ClearWorkSpace();
            try
            {
                FolderBrowserDialog fbd = new FolderBrowserDialog();
                fbd.SelectedPath = absPath;
                fbd.Description = "选择皮肤的工作目录, 加载皮肤相关的资源和配置文件";
                if (fbd.ShowDialog() == DialogResult.OK)
                {
                    absPath = fbd.SelectedPath;
                    currentPath = "";
                    folderPath = Path.GetFileName(absPath);
                    DirectoryInfo dirInfo = new DirectoryInfo(absPath);
                    foreach (FileInfo fileInfo in dirInfo.GetFiles())
                    {
                        if (fileInfo.Extension.ToLower().Equals(".ini"))
                        {
                            configName = fileInfo.FullName;
                            break;
                        }
                    }
                    if (File.Exists(Path.Combine(absPath, configName)))
                    {
                        this.updateWorkspaceLV(absPath);
                        this.workspaceLV.AllowDrop = true;
                        this.AnalyseIniAndShow();
                    }
                    else
                    {
                        MessageBox.Show("(⊙o⊙), 找不到配置文件啊亲，你别逗我了~~~，请确保配置文件存在且扩展名是.ini");
                    }
                }
                fbd.Dispose();
            }
            catch (Exception ex)
            {
                MessageBox.Show("~`·_·`~好像发生了点什么问题， 联系作者吧^_^ :" + ex.Message, "错误", 0, MessageBoxIcon.Error);
            }
        }
        #endregion

        #region 保存皮肤
        private void saveTSMI_Click(object sender, EventArgs e)
        {
            StringBuilder errSave = new StringBuilder();
            INIOperationClass iniRwTool = new INIOperationClass(Path.Combine(absPath, configName));
            foreach (KeyValuePair<String, VariablesClass.ProgramObject> kvPair in Program.progList)
            {
                if (!iniRwTool.INIWriteValue("Variables", kvPair.Key, kvPair.Value.ProgPath + kvPair.Value.ProgArgs))
                    errSave.AppendLine("变量" + kvPair.Key + "保存失败！");
            }
            foreach (MyPictureBox pb in this.controlList)
            {
                if (iniRwTool.INIWriteValue(pb.Name.ToString(), "Meter", "Image"))
                {
                    Boolean state = true;
                    String MeterName = pb.Name.ToString();
                    pb.ImagePath = pb.ImagePath.Replace(Path.Combine(absPath, "@Resources"), "#@#");
                    pb.ImagePath = pb.ImagePath.Replace(absPath, "#CURRENTPATH#");

                    state &= iniRwTool.INIWriteValue(MeterName, "ImageName", pb.ImagePath);
                    state &= iniRwTool.INIWriteValue(MeterName, "X", pb.RelLocation.X.ToString());
                    state &= iniRwTool.INIWriteValue(MeterName, "Y", pb.RelLocation.Y.ToString());

                    foreach (KeyValuePair<String, String> kvPair in pb.GetActionList())
                    {
                        String actionName = kvPair.Key;
                        String action = kvPair.Value;

                        state &= iniRwTool.INIWriteValue(MeterName, actionName, action);
                    }

                }
                else
                {
                    MessageBox.Show(pb.Name.ToString() + "保存失败");
                }
            }
            MessageBox.Show("^_^ 保存成功啦， 把皮肤文件夹拷贝到Rainmeter的Skin目录下， 去看看效果吧");
        }
        #endregion

        #region 项目试图的拖拽事件
        private void wsLV_ItemDrag(object sender, ItemDragEventArgs e)
        {
            if (e.Button == System.Windows.Forms.MouseButtons.Left)
            {
                ListView lv = (ListView)sender;
                int index = lv.FocusedItem.Index;
                if (index > 0)
                {
                    lv.DoDragDrop(lv.FocusedItem, DragDropEffects.All);
                }
            }
        }

      
        private void wsLV_DragEnter(object sender, DragEventArgs e)
        {
            e.Effect = DragDropEffects.Copy;
        }

        private void wsLV_DragDrop(object sender, DragEventArgs e)
        {
            e.Effect = DragDropEffects.Copy;
            System.Array fileArray = ((System.Array)e.Data.GetData(DataFormats.FileDrop));
            for (Int32 i = 0; i < fileArray.Length; ++i)
            {
                String file = fileArray.GetValue(i).ToString();
                try
                {
                    File.Copy(file, Path.Combine(absPath, Path.GetFileName(file)));
                }
                catch (Exception ex)
                {
                    MessageBox.Show("拷贝文件出错了0.0 " + ex.Message);
                }
                // MessageBox.Show(file);
            }
            this.updateWorkspaceLV(absPath);
        }
        #endregion

        #region 工作视图拽入
        private void PicBox_DragEnter(object sender, DragEventArgs e)
        {
            e.Effect = DragDropEffects.Copy;
        }

        private void PicBox_DragDrop(object sender, DragEventArgs e)
        {
            try
            {
                e.Effect = DragDropEffects.Copy;
                ListViewItem item = (ListViewItem)e.Data.GetData(typeof(ListViewItem));
                String fileName = item.Text;
                if (Path.GetExtension(fileName).ToLower().Equals(".ini"))
                {
                    configName = fileName;
                    this.ClearWorkSpace();
                    this.AnalyseIniAndShow();
                }
                else
                {
                    String imagePath = Path.Combine(absPath, Path.Combine(currentPath, fileName));
                    Stream s = File.Open(imagePath, FileMode.Open);
                    Image img = Image.FromStream(s);
                    MyPictureBox pb = new MyPictureBox(img);
                    //  BitmapRegion.CreateControlRegion(pb, new Bitmap(img));
                    pb.Name = "Image_" + this.tmpNameCount++;
                    pb.ImagePath = imagePath;
                    Point reMousePoint = panel1.PointToClient(Control.MousePosition);
                    pb.Location = new Point(reMousePoint.X - pb.Size.Width / 2, reMousePoint.Y - pb.Size.Height / 2);
                    pb.RelLocation = new Point(pb.Location.X + panel1.HorizontalScroll.Value, pb.Location.Y + panel1.VerticalScroll.Value);
                    pb.Cursor = Cursors.Hand;
                    pb.ContextMenuStrip = this.picBoxCMS;

                    ///picbox event region start
                    pb.AllowDrop = true;
                    pb.DragDrop += new DragEventHandler(PicBox_DragDrop);
                    pb.DragEnter += new DragEventHandler(PicBox_DragEnter);
                    pb.MouseDown += new MouseEventHandler(PicBox_MouseDown);
                    pb.MouseUp += new MouseEventHandler(PicBox_MouseUp);

                    ///更新提示
                    StringBuilder tips = new StringBuilder();
                    tips.AppendLine(pb.Name.ToString());
                    tips.AppendLine(pb.RelLocation.ToString());
                    foreach (KeyValuePair<String, String> kvPair in pb.GetActionList())
                    {
                        String action = kvPair.Value;
                        tips.AppendLine(kvPair.Key + ":" + action);
                    }
                    toolTip1.SetToolTip(pb, tips.ToString());
                    ///picbox event region end

                    mainPicBox.Controls.Add(pb);
                    pb.BringToFront();
                    s.Close();
                    controlList.Add(pb);
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "错误", 0, MessageBoxIcon.Error);
            }
        }
        #endregion

        /// <summary>
        /// 更新属性面板
        /// </summary>
        /// <param name="panel">目标控件</param>
        private void updateProperties(PanelExtend panel)
        {
            nameTextBox.Text = panel.Name;
            if (panel is MyPictureBox)
            {
                MyPictureBox pb = panel as MyPictureBox;
                xPosTextBox.Text = pb.RelLocation.X.ToString();
                yPosTextBox.Text = pb.RelLocation.Y.ToString();
                wSizeTextBox.Text = pb.Size.Width.ToString();
                hSizeTextBox.Text = pb.Size.Height.ToString();
            }
            else if (panel is MyLabel)
            {
                MyLabel label = panel as MyLabel;
                xPosTextBox.Text = label.RelLocation.X.ToString();
                yPosTextBox.Text = label.RelLocation.Y.ToString();
                wSizeTextBox.Text = label.Size.Width.ToString();
                hSizeTextBox.Text = label.Size.Height.ToString();
            }
        }

        #region 图片在panel1范围内拖动
        /// <summary>
        /// 鼠标按下，开始拖动
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void PicBox_MouseDown(object sender, MouseEventArgs e)
        {
            MyPictureBox pb = (MyPictureBox)sender;
            currentControl = pb;
            this.updateProperties(pb);
            ///添加鼠标移动事件 开始拖动
            lastMousePosition = panel1.PointToClient(Control.MousePosition);
            pb.MouseMove += new MouseEventHandler(PicBox_MouseMove);
        }

        private void PicBox_MouseUp(object sender, MouseEventArgs e)
        {
            MyPictureBox pb = (MyPictureBox)sender;
            ///解除鼠标移动事件 完成拖动
            pb.MouseMove -= new MouseEventHandler(PicBox_MouseMove);

            ///更新提示
            StringBuilder tips = new StringBuilder();
            tips.AppendLine(pb.Name.ToString());
            tips.AppendLine(pb.RelLocation.ToString());
            foreach (KeyValuePair<String, String> kvPair in pb.GetActionList())
            {
                String action = kvPair.Value;
                tips.AppendLine(kvPair.Key + ":" + action);
            }
            toolTip1.SetToolTip(pb, tips.ToString());
        }
        /// <summary>
        /// 拖动前的原picbox坐标
        /// </summary>
        private Point lastMousePosition;

        /// <summary>
        /// 鼠标移动事件 注：拖动条不够人性化， 仍需改进
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void PicBox_MouseMove(object sender, MouseEventArgs e)
        {
            if (e.Button == System.Windows.Forms.MouseButtons.Right) return;
            try
            {
                MyPictureBox pb = (MyPictureBox)sender;

                Point reMousePoint = panel1.PointToClient(Control.MousePosition);
                Int32 _X = reMousePoint.X + pb.Location.X - lastMousePosition.X;
                Int32 _Y = reMousePoint.Y + pb.Location.Y - lastMousePosition.Y;
                lastMousePosition = reMousePoint;
                if (_X < 0)
                {
                    panel1.HorizontalScroll.Value = 0;
                    _X = 0;
                }
                if (_Y < 0)
                {
                    panel1.VerticalScroll.Value = 0;
                    _Y = 0;
                }
                if (_X > panel1.Width - pb.Width)
                {
                    panel1.HorizontalScroll.Value = Screen.PrimaryScreen.Bounds.Width - panel1.Width;
                    _X = panel1.Width - pb.Width;
                }
                if (_Y > panel1.Height - pb.Height)
                {
                    panel1.VerticalScroll.Value = Screen.PrimaryScreen.Bounds.Height - panel1.Height;
                    _Y = panel1.Height - pb.Height;
                }
                pb.Location = new Point(_X, _Y);
                pb.RelLocation = new Point(pb.Location.X + panel1.HorizontalScroll.Value, pb.Location.Y + panel1.VerticalScroll.Value);
            }
            catch
            {
                panel1.HorizontalScroll.Value = 0;
                panel1.VerticalScroll.Value = 0; ;
            }
        }
        #endregion

        #region Label在panel1范围内拖动
        /// <summary>
        /// 鼠标按下，开始拖动
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Label_MouseDown(object sender, MouseEventArgs e)
        {
            MyLabel label = (MyLabel)sender;
            ///添加鼠标移动事件 开始拖动
            lastMousePosition = panel1.PointToClient(Control.MousePosition);
            label.MouseMove += new MouseEventHandler(Label_MouseMove);
        }

        private void Label_MouseUp(object sender, MouseEventArgs e)
        {
            MyLabel label = (MyLabel)sender;
            ///解除鼠标移动事件 完成拖动
            label.MouseMove -= new MouseEventHandler(Label_MouseMove);

            toolTip1.SetToolTip(label, label.Text.ToString());
        }

        /// <summary>
        /// 鼠标移动事件 注：拖动条不够人性化， 仍需改进
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Label_MouseMove(object sender, MouseEventArgs e)
        {
            if (e.Button == System.Windows.Forms.MouseButtons.Right) return;
            try
            {
                MyLabel label = (MyLabel)sender;

                Point reMousePoint = panel1.PointToClient(Control.MousePosition);
                Int32 _X = reMousePoint.X + label.Location.X - lastMousePosition.X;
                Int32 _Y = reMousePoint.Y + label.Location.Y - lastMousePosition.Y;
                lastMousePosition = reMousePoint;
                if (_X < 0)
                {
                    panel1.HorizontalScroll.Value = 0;
                    _X = 0;
                }
                if (_Y < 0)
                {
                    panel1.VerticalScroll.Value = 0;
                    _Y = 0;
                }
                if (_X > panel1.Width - label.Width)
                {
                    panel1.HorizontalScroll.Value = Screen.PrimaryScreen.Bounds.Width - panel1.Width;
                    _X = panel1.Width - label.Width;
                }
                if (_Y > panel1.Height - label.Height)
                {
                    panel1.VerticalScroll.Value = Screen.PrimaryScreen.Bounds.Height - panel1.Height;
                    _Y = panel1.Height - label.Height;
                }
                label.Location = new Point(_X, _Y);
                label.RelLocation = new Point(label.Location.X + panel1.HorizontalScroll.Value, label.Location.Y + panel1.VerticalScroll.Value);
            }
            catch
            {
                panel1.HorizontalScroll.Value = 0;
                panel1.VerticalScroll.Value = 0; ;
            }
        }
        #endregion

        #region 目录区域处理
        /// <summary>
        /// 工作目录双击进入文件夹
        /// </summary>
        /// <param name="sender">触发源</param>
        /// <param name="e">事件参数</param>
        private void wsLV_MouseDbClick(object sender, MouseEventArgs e)
        {
            if (e.Button == System.Windows.Forms.MouseButtons.Left)
            {
                //当前触发操作的项的下标
                int index = workspaceLV.FocusedItem.Index;
                //当前触发操作的项的名称
                string node = workspaceLV.FocusedItem.Text;
                string newPath = "";
                try
                {
                    if (index == 0 && node.Equals("返回上层"))
                    {
                        newPath = Path.GetDirectoryName(currentPath);
                    }
                    else
                    {
                        newPath = Path.Combine(currentPath, node);
                    }
                    bool di = new DirectoryInfo(Path.Combine(absPath, newPath)).Exists;
                    if (di == false)
                    {
                        System.Diagnostics.Process.Start(Path.Combine(absPath, newPath));
                    }
                    else
                    {
                        updateWorkspaceLV(Path.Combine(absPath, newPath));
                        currentPath = newPath;
                    }
                }
                catch
                {
                    return;
                }
            }
        }
        #endregion

        #region 工作区域右击弹出菜单处理
        /// <summary>
        /// 更改meter的名字
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void renPicBoxCSMI_Click(object sender, EventArgs e)
        {
            ContextMenuStrip cms = (ContextMenuStrip)((ToolStripMenuItem)sender).Owner;
            MyPictureBox pb = (MyPictureBox)cms.SourceControl;
            InputBoxForm ibf = new InputBoxForm();
            ibf.Value = pb.Name.ToString();
            ibf.ShowDialog();
            if (ibf.Value != null)
            {
                pb.Name = ibf.Value;

                ///更新提示
                StringBuilder tips = new StringBuilder();
                tips.AppendLine(pb.Name.ToString());
                tips.AppendLine(pb.RelLocation.ToString());
                foreach (KeyValuePair<String, String> kvPair in pb.GetActionList())
                {
                    String action = kvPair.Value;
                    tips.AppendLine(kvPair.Key + ":" + action);
                }
                toolTip1.SetToolTip(pb, tips.ToString());
            }
            ibf.Dispose();
        }

        /// <summary>
        /// 删除控件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void delPicBoxCMSI_Click(object sender, EventArgs e)
        {
            ContextMenuStrip cms = (ContextMenuStrip)((ToolStripMenuItem)sender).Owner;
            MyPictureBox srcPicBox = (MyPictureBox)cms.SourceControl;
            String warnMsg = "你正在尝试删除控件" + srcPicBox.Tag + "删除后不可撤销，确定删除？";

            if (MessageBox.Show(warnMsg, "删除控件", MessageBoxButtons.YesNo, MessageBoxIcon.Warning) == DialogResult.Yes)
            {
                controlList.Remove(srcPicBox);
                mainPicBox.Controls.Remove(srcPicBox);
                srcPicBox.Dispose();
            }
        }

        /// <summary>
        /// 属性
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void propertiesCMSI_Click(object sender, EventArgs e)
        {
            ContextMenuStrip cms = (ContextMenuStrip)((ToolStripMenuItem)sender).Owner;
            currentControl = cms.SourceControl as PanelExtend;
            tabControl1.SelectTab(1);
            this.updateProperties(currentControl);
        }
               

        /// <summary>
        /// 二级菜单触发 用于左键单击事件绑定
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void lftClkBangTSMI_Click(object sender, EventArgs e)
        {
            MyPictureBox pb = (MyPictureBox)this.srcCtrlOfPicBoxCMS;
            SetActionForm saf = new SetActionForm();

            //OpenFileDialog ofd = new OpenFileDialog();
            saf.ShowDialog();
            String action = saf.Action;
            if (!String.IsNullOrEmpty(action))
            {
                pb.AddAction("LeftMouseUpAction", action);

                ///更新提示
                StringBuilder tips = new StringBuilder();
                tips.AppendLine(pb.Name.ToString());
                tips.AppendLine(pb.RelLocation.ToString());
                foreach (KeyValuePair<String, String> kvPair in pb.GetActionList())
                {
                    action = kvPair.Value;
                    tips.AppendLine(kvPair.Key + ":" + action);
                }
                toolTip1.SetToolTip(pb, tips.ToString());
            }
            saf.Dispose();
        }

        /// <summary>
        /// 二级菜单触发 用于左键双击菜单绑定
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void lftDbClkBangTSMI_Click(object sender, EventArgs e)
        {
            MyPictureBox pb = (MyPictureBox)this.srcCtrlOfPicBoxCMS;
            SetActionForm saf = new SetActionForm();

            //OpenFileDialog ofd = new OpenFileDialog();
            saf.ShowDialog();
            String action = saf.Action;
            if (!String.IsNullOrEmpty(action))
            {
                pb.AddAction("LeftMouseDoubleClickAction", action);

                ///更新提示
                StringBuilder tips = new StringBuilder();
                tips.AppendLine(pb.Name.ToString());
                tips.AppendLine(pb.RelLocation.ToString());

                foreach (KeyValuePair<String, String> kvPair in pb.GetActionList())
                {
                    action = kvPair.Value;
                    tips.AppendLine(kvPair.Key + ":" + action);
                }
                toolTip1.SetToolTip(pb, tips.ToString());
            }
            saf.Dispose();
        }

        private void lftDownBangCMSI_Click(object sender, EventArgs e)
        {
            MyPictureBox pb = (MyPictureBox)this.srcCtrlOfPicBoxCMS;
            SetActionForm saf = new SetActionForm();

            saf.ShowDialog();
            String action = saf.Action;
            if (!String.IsNullOrEmpty(action))
            {
                pb.AddAction("LeftMouseDownAction", action);

                ///更新提示
                StringBuilder tips = new StringBuilder();
                tips.AppendLine(pb.Name.ToString());
                tips.AppendLine(pb.RelLocation.ToString());

                foreach (KeyValuePair<String, String> kvPair in pb.GetActionList())
                {
                    action = kvPair.Value;
                    tips.AppendLine(kvPair.Key + ":" + action);
                }
                toolTip1.SetToolTip(pb, tips.ToString());
            }
            saf.Dispose();
        }

        private void hoverBangTSMI_Click(object sender, EventArgs e)
        {

        }


        /// <summary>
        /// 二级菜单弹出事件， 用于保存ContextMenuStrip的sourcecontrol数据
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void bPBCSMI_DropDownOpening(object sender, EventArgs e)
        {
            ContextMenuStrip cms = (ContextMenuStrip)((ToolStripMenuItem)sender).Owner;
            this.srcCtrlOfPicBoxCMS = cms.SourceControl;
        }

        /// <summary>
        /// 移至顶层
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void bringToFrontTSMI_Click(object sender, EventArgs e)
        {
            MyPictureBox pb = (MyPictureBox)this.srcCtrlOfPicBoxCMS;
            pb.BringToFront();
        }

        /// <summary>
        /// 移至底层
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void sendToBackTSMI_Click(object sender, EventArgs e)
        {
            MyPictureBox pb = (MyPictureBox)this.srcCtrlOfPicBoxCMS;
            pb.SendToBack();
        }

        /// <summary>
        /// 层管理菜单弹出触发事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void lvlCtrl_DropDownOpening(object sender, EventArgs e)
        {
            ContextMenuStrip cms = (ContextMenuStrip)((ToolStripMenuItem)sender).Owner;
            this.srcCtrlOfPicBoxCMS = cms.SourceControl;
        }


        #endregion

        /// <summary>
        /// 程序变量定义窗口
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void progDefTSMI_Click(object sender, EventArgs e)
        {
            ProgDefForm pdf = new ProgDefForm();
            pdf.Show(this);
        }

        /// <summary>
        /// 关于窗口
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void aboutTSMI_Click(object sender, EventArgs e)
        {
            AboutForm aboutForm = new AboutForm();
            aboutForm.ShowDialog();
        }

        /// <summary>
        /// 帮助菜单
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void helpTSMI_Click(object sender, EventArgs e)
        {
            String filePath = Path.Combine(System.IO.Path.GetTempPath(), "RainMeterCustomized_ReadMe.txt");
            StreamWriter sw = File.CreateText(filePath);
            sw.Write(Properties.Resources.README);
            sw.Close();
            System.Diagnostics.Process.Start("notepad.exe", filePath);
        }

        /// <summary>
        /// 弹出更新日志
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void updateTSMI_Click(object sender, EventArgs e)
        {
            String filePath = Path.Combine(System.IO.Path.GetTempPath(), "RainMeterCustomized_UpdateLog.txt");
            StreamWriter sw = File.CreateText(filePath);
            sw.Write(Properties.Resources.UPDATELOG);
            sw.Close();
            System.Diagnostics.Process.Start("notepad.exe", filePath);
        }

        /// <summary>
        /// 退出
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void exitTSMI_Click(object sender, EventArgs e)
        {
            if (MessageBox.Show("关闭前请确保已经保存您的皮肤， 确定关闭？", "关闭窗口", MessageBoxButtons.YesNo) == DialogResult.Yes)
            {
                Close();
            }
        }

        #region  虚拟桌面背景更换
        /// <summary>
        /// 获取系统信息， 此处获取系统背景图片地址
        /// </summary>
        /// <param name="uAction"></param>
        /// <param name="uParam"></param>
        /// <param name="lpvParam"></param>
        /// <param name="fuWinIni"></param>
        /// <returns></returns>
        [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        public static extern int SystemParametersInfo(int uAction, int uParam, StringBuilder lpvParam, int fuWinIni);
        private const int SPI_GETDESKWALLPAPER = 0x0073;


        private void sysBgCMSI_Click(object sender, EventArgs e)
        {
            //定义存储缓冲区大小
            StringBuilder sb = new StringBuilder(200);

            //获取Window 桌面背景图片地址，使用缓冲区
            SystemParametersInfo(SPI_GETDESKWALLPAPER, 200, sb, 0);

            //缓冲区中字符进行转换
            String filePath = sb.ToString(); //系统桌面背景图片路径
            Stream stream = null;
            Image img = null;
            try
            {
                stream = File.OpenRead(filePath);
                img = Image.FromStream(stream);
                stream.Close();
            }
            catch
            {
                MessageBox.Show("获取桌面背景图失败， 用默认背景代替！");
                img = Properties.Resources.ali;
            }
            Image img2 = new Bitmap(Screen.PrimaryScreen.Bounds.Width, Screen.PrimaryScreen.Bounds.Height);
            Graphics graphics = Graphics.FromImage(img2);
            panel1.Size = img2.Size;
            this.mainPicBox.Size = img2.Size;
            graphics.DrawImage(img, new Rectangle(0, 0, img2.Width, img2.Height));
            this.mainPicBox.Image = img2;
            graphics.Dispose();
        }

        private void selfDefBgCMSI_Click(object sender, EventArgs e)
        {
            OpenFileDialog ofd = new OpenFileDialog();
            ofd.Filter = "(*.BMP;*.JPG;*.JPEG;*.PNG;*.GIF)|*.BMP;*.JPG;*.JPEG;*.PNG;*.GIF";
            if (ofd.ShowDialog() == System.Windows.Forms.DialogResult.OK)
            {
                String filePath = ofd.FileName;
                Stream stream = File.OpenRead(filePath);
                Image img = Image.FromStream(stream);
                stream.Close();
                Image img2 = new Bitmap(Screen.PrimaryScreen.Bounds.Width, Screen.PrimaryScreen.Bounds.Height);
                Graphics graphics = Graphics.FromImage(img2);
                panel1.Size = img2.Size;
                this.mainPicBox.Size = img2.Size;
                graphics.DrawImage(img, new Rectangle(0, 0, img2.Width, img2.Height));
                this.mainPicBox.Image = img2;
                graphics.Dispose();
            }
        }
        #endregion

        /// <summary>
        /// 字体定义窗口
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void fontDefTSMI_Click(object sender, EventArgs e)
        {
            FontDefForm fdf = new FontDefForm();
            fdf.Show();
        }

        private void xPosTextBox_TextChanged(object sender, EventArgs e)
        {
            Int32 _X = currentControl.Location.X;
            try
            {
                _X = Convert.ToInt32((sender as TextBox).Text);
            }
            catch
            {
            }
            currentControl.Location = new Point(_X, currentControl.Location.Y);
            currentControl.Invalidate();
            currentControl.Refresh();
        }

        

       

    }

}

   

